iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0
Modern Web

一起來玩圖像編輯器:Fabric.js 的實戰修煉系列 第 25

Day25-為什麼 fabric.js 會有兩層畫布

  • 分享至 

  • xImage
  •  

Q: 為什麼fabricjs會有兩層畫布

咦~ 我的 download button 下面明明就只有寫一個 id 是 my-canvas 的畫布。
為什麼打開 element 看 render 出來的 html,竟然是用 canvas-container 這個 div 包著的兩個 canvas??

ˇ 在編輯器裡寫的 html
https://ithelp.ithome.com.tw/upload/images/20240829/20168354eSSArItzcK.png

ˇ render 出來的 html
https://ithelp.ithome.com.tw/upload/images/20240829/20168354w8d2GBz0rl.png

A: 獨立處理不同的渲染任務,從而提高效率和靈活性

Fabric.js 的 canvas 會有兩層,主要是因為它使用了兩個 HTML canvas 元素來管理和渲染圖形。這種設計允許 Fabric.js 在不同的層上獨立處理不同的渲染任務,從而提高效率和靈活性。這兩層通常包括:

下層畫布(lower-canvas)

static canvas 靜態顯示層 (靜態下層)
用於渲染靜態圖像或背景圖案。這層不經常更新,只有在背景圖像或圖案改變時才重新渲染。
雖說不常更新,但如果使用動畫,也會是渲染在這一層。

  • 存儲了畫布上所有對象的實際視覺表現。
  • 當對象不在交互狀態時,它們的圖像會被繪製在這個畫布上。
  • 性能優化:因為這層不經常更新,所以可以減少重繪的次數,提高性能。
    顯示 => 畫布上所有跟使用者沒有互動的東西(非選取中的物件)

上層畫布(upper-canvas)

interactive canvas 使用者互動層 (互動上層)
用於渲染動態元素,如用戶正在繪製的形狀、選擇的對象邊框等。這層會頻繁更新,以響應用戶的互動。

  • 主要用於處理交互和動態效果。
  • 用於繪製交互控件,如對象的邊界框、旋轉控件等。
  • 當用戶與對象交互時(如選擇、拖動、調整大小),這些臨時效果會在上層畫布上繪製。
  • 滑鼠事件(如點擊、拖拽)是在這層畫布上處理的。
    顯示 => 正在拖曳的物件、選取中的物件的控制項、free draw 正在畫的線段

使用兩層 canvas 的好處包括:

1. 清晰的職責分離:

  • 下層負責內容渲染。
  • 上層負責交互和動態效果。

2. 性能優化

  • 靜態內容保持在下層,減少了不必要的重繪。
  • 只有在交互時才需要更新上層畫布,這大大提高了性能。

3. 渲染效率

  • 動態層只需要在有變化時重繪,而背景層則可以保持不變,這樣可以有效地利用瀏覽器的渲染資源。
  • 上層只需專心處理當前使用者行為就好。

4. 靈活性和控制

  • 開發者可以更精細地控制不同層的渲染過程,例如,可以獨立更新動態元素而不影響背景層,或者在需要時只重繪一個層。

舉個例子:顯示的分工

這邊的分工是

  • 靜態下層 lower-canvas:顯示綠色圓圈
  • 互動上層 upper-canvas:顯示淺藍控制框
    img-ex
    關於性能優化,減少了不必要的重繪:
    指的是像我們選取物件,但也沒有對物件屬性做改變(改變顏色、位置、形狀等)
    其實對畫面本體圖像靜態下層 lower-canvas 是沒有改變的,所以下層並不需要重新渲染。

對他做了 選取 > 取消選取 > 又再度選取
這個使用者行為&控制框的顯示只要讓 互動上層 upper-canvas 來忙就好XD,不關靜態下層 lower-canvas的事。

舉第二個 🌰:渲染的排序

這裡我先設置了一張圖當前景圖(overlayImage),
並在上面畫畫。

img

在這個畫布上前景圖 overlayImage 應該要是在所有物件的最上層,而且不可能被蓋過的。
那為什麼我們用 free draw 塗鴉,正在畫的線條卻會在最頂的前景圖 overlayImage 之上??
這不合理呀?!

前景圖背景圖(overlayImage, backgroundImage)詳細介紹可以看這邊:Day14-畫布背景處理:設置和操作畫布背景(前景圖背景圖)

耶嘿
但你從前面讀到了這裡,所以你知道😎

因為...
就算 overlayImage 再怎麼上層,他也只是在 lower-canvas(靜態下層)的最頂。
而我們正在畫圖的動作 & 產生出來的線條,在放掉滑鼠結束互動之前,是正在互動的 upper-canvas(互動上層) 在負責渲染的。

至於為什麼一放掉滑鼠,將線條變為物件時,就會突然跑到下層呢?
這是因為,此時的線條已結束與使用者的互動了,這時轉為由 lower-canvas(靜態下層) 接管,而在 lower-canvas(靜態下層)裡,排序最頂的就是 overlayImage 了。
所以線條立馬回歸他該遵守的規則:排在 overlayImage 老大的後面。

本例 codepen


上一篇
Day24-掌握Fabric.js核心-常用API模式剖析總整理
下一篇
Day26-所以說 fabric.js 到底可以做出什麼東西?-別人的作品賞析
系列文
一起來玩圖像編輯器:Fabric.js 的實戰修煉30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言